package com.tianji.aigc.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.ObjUtil;
import cn.hutool.core.util.RandomUtil;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.tianji.aigc.config.SessionProperties;
import com.tianji.aigc.entity.ChatSession;
import com.tianji.aigc.enums.MessageTypeEnum;
import com.tianji.aigc.mapper.ChatSessionMapper;
import com.tianji.aigc.memory.CustomizeAssistantMessage;
import com.tianji.aigc.service.ChatService;
import com.tianji.aigc.service.ChatSessionService;
import com.tianji.aigc.vo.ChatSessionVO;
import com.tianji.aigc.vo.SessionDetailVO;
import com.tianji.aigc.vo.SessionVO;
import com.tianji.common.utils.CollUtils;
import com.tianji.common.utils.UserContext;
import lombok.RequiredArgsConstructor;
import org.springframework.ai.chat.memory.ChatMemory;
import org.springframework.ai.chat.messages.Message;
import org.springframework.ai.chat.messages.MessageType;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.temporal.ChronoUnit;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author zgp
 * @version V1.0
 * @date 2025-04-21 12:22
 */
@Service
@RequiredArgsConstructor
public class ChatSessionServiceImpl extends ServiceImpl<ChatSessionMapper, ChatSession> implements ChatSessionService {
    private final SessionProperties sessionProperties;
    private final ChatMemory chatMemory;
    // 历史消息数量，默认1000条
    public static final int HISTORY_MESSAGE_COUNT = 1000;

    /**
     * 会话创建
     *
     * @param num 热门问题数量
     * @return
     */
    @Override
    public SessionVO createSession(Integer num) {
        // 1. 设置助手默认标题、热门问题数据
        SessionVO sessionVO = BeanUtil.toBean(sessionProperties, SessionVO.class);
        sessionVO.setExamples(RandomUtil.randomEleList(sessionProperties.getExamples(), num));
        sessionVO.setSessionId(IdUtil.fastSimpleUUID());
        // 2. 持久化会话数据
        ChatSession chatSession = new ChatSession();
        chatSession.setSessionId(sessionVO.getSessionId());
        chatSession.setUserId(UserContext.getUser());
        save(chatSession);
        return sessionVO;
    }

    /**
     * 获取热门问题列表
     *
     * @param num 数量
     * @return
     */
    @Override
    public List<SessionVO.Example> hotQuestions(Integer num) {
        List<SessionVO.Example> examples = new ArrayList<>();
        examples.addAll(RandomUtil.randomEleList(sessionProperties.getExamples(), num));
        return examples;
    }

    /**
     * 查询会话详情
     *
     * @param sessionId 会话id
     * @return
     */
    @Override
    public List<SessionDetailVO> getSessionDetail(String sessionId) {
        String conversationId = ChatService.getConversationId(sessionId);
        List<Message> messages = chatMemory.get(conversationId, DEFAULT_BATCH_SIZE);
        if (CollUtils.isEmpty(messages)) {
            return List.of();
        }
        // 遍历构建会话详情数据
        return messages.stream()
                .filter(message -> MessageType.USER == message.getMessageType()
                        || MessageType.ASSISTANT == message.getMessageType())
                .map(message -> {
                            if (message instanceof CustomizeAssistantMessage) {
                                // 如果是自定义的助手消息，则设置附加参数信息
                                return SessionDetailVO.builder()
                                        .type(MessageTypeEnum.valueOf(message.getMessageType().name()))
                                        .content(message.getText())
                                        .params(((CustomizeAssistantMessage) message).getParams())
                                        .build();
                            }
                            // 转换为SessionDetailVO
                            return SessionDetailVO.builder()
                                    // valueOf方法：用于根据枚举名称("USER"，“ASSISTANT”)获取枚举实例
                                    // name方法：获取枚举实例的名称
                                    .type(MessageTypeEnum.valueOf(message.getMessageType().name()))
                                    .content(message.getText())
                                    .build();
                        }
                ).toList();
    }

    /**
     * 异步：更新会话标题
     *
     * @param sessionId 会话id
     * @param userId    用户id
     * @param title     标题
     */
    @Async
    @Override
    public void updateSessionTitle(String sessionId, Long userId, String title) {
        ChatSession chatSession = this.lambdaQuery()
                .eq(ChatSession::getSessionId, sessionId)
                .eq(ChatSession::getUserId, userId)
                .one();
        if(ObjUtil.isEmpty(chatSession)){
            return;
        }
        if(StrUtil.isNotBlank(title) && StrUtil.isBlank(chatSession.getTitle())){
            // 仅当会话标题为空时，才设置会话标题
            chatSession.setTitle(StrUtil.sub(title, 0, 100));
        }
        // 设置更新时间
        chatSession.setUpdateTime(LocalDateTime.now());
        // 更新会话标题
        this.updateById(chatSession);
    }

    /**
     * 查询历史会话列表
     *
     * @return
     */
    @Override
    public Map<String, List<ChatSessionVO>> history() {
        final String TODAY = "当天";
        final String LAST_30_DAYS = "最近30天";
        final String LAST_YEAR = "最近1年";
        final String MORE_THAN_YEAR = "1年以上";
        Long userId = UserContext.getUser();
        // 查询用户会话列表， 限制返回30条，且会话title不能为空
        List<ChatSession> chatSessions = this.lambdaQuery()
                .eq(ChatSession::getUserId, userId)
                .isNotNull(ChatSession::getTitle)
                .orderByDesc(ChatSession::getUpdateTime)
                .last("limit 30")
                .list();
        if(CollUtils.isEmpty(chatSessions)){
            return Map.of();
        }
        LocalDate now = LocalDate.now();
        // 数据分组并构建响应数据
        return chatSessions.stream()
                .map(chatSession -> BeanUtil.toBean(chatSession, ChatSessionVO.class))
                .collect(Collectors.groupingBy(chatSessionVO -> {
                    long between = Math.abs(ChronoUnit.DAYS.between(chatSessionVO.getUpdateTime().toLocalDate(), now));
                    if(between == 0){
                        return TODAY;
                    }else if(between <= 30){
                        return LAST_30_DAYS;
                    }else if(between <= 365){
                        return LAST_YEAR;
                    }else {
                        return MORE_THAN_YEAR;
                    }
                }));
    }

    /**
     * 修改历史会话标题
     *
     * @param sessionId 会话id
     * @param title     标题
     */
    @Override
    public void modifyHistorySessionTitle(String sessionId, String title) {
        ChatSession chatSession = this.lambdaQuery()
                .eq(ChatSession::getSessionId, sessionId)
                .one();
        if(ObjUtil.isEmpty(chatSession)){
            return;
        }
        // 修改会话标题
        chatSession.setTitle(StrUtil.sub(title, 0, 100));
        this.updateById(chatSession);
    }

    /**
     * 删除历史会话
     *
     * @param sessionId 会话id
     */
    @Override
    @Transactional(rollbackFor = {Exception.class})
    public void deleteHistorySession(String sessionId) {
        // 删除会话数据
        this.remove(Wrappers.<ChatSession>lambdaQuery().eq(ChatSession::getSessionId, sessionId));
        // 持久化后的会话记录数据
        chatMemory.clear(ChatService.getConversationId(sessionId));
    }
}
